package main

import "fmt"

/*===闭包===
		- 闭包是有捕获列表的Function Value()
    - 特点：
		1. 解决局部变量不能被外部访问的一种解决方案
		2. 是把函数当作一种方法返回值的应用
*/
//TODO 闭包函数调用内存分配
func main() {

	f1 := closure()
	fmt.Println(f1()) //2
	fmt.Println(f1()) //3
	fmt.Println(f1()) //4

	f2 := closure()
	/* [note] f1 与 f2在栈上的地址实际是分别指向堆上不同的捕获列表，
	每一个捕获列表
	*/
	fmt.Println("f2", f2()) //2
	fmt.Println("f2", f2()) //3

	/* [note] 闭包有新的返回函数f2，但是原返回函数f仍然存在 */
	fmt.Println(f1()) //5

	/* [note] 闭包返回的函数在内存中是同一个函数 */
	fmt.Printf("内存地址：[f]%p [f2]%p \n", f1, f2)

	fmt.Printf("function value addr：[f]%p [f2]%p \n", f1, f2)

}

func closure() func() int {
	i := 1
	return func() int {
		fmt.Printf("当前函数变量i的地址 ：%p \n", &i)
		i++
		return i
	}
}
